#!/bin/bash
#参考:https://github.com/emptyhua/bash-pinyin-completion
#参考:http://linuxtoy.org/archives/chsdir.html
#参考:/etc/bash_completion

#用于保存覆盖之前的函数
#from http://mivok.net/2009/09/20/bashfunctionoverride.html

# 支持 atom open 等
# 在 /usr/local/etc/bash_completion 文件中 makeinfo and texi2dvi are defined elsewhere 的下一行添加上 atom 和 open 即可。

__logfile=~/command/pinyin.log
__HAS_LOG=0
__MYLOG() {
    if [ "$__HAS_LOG" = "1" ];then
        echo "$@" >> ${__logfile}
    fi
}
_py_save_function() {
    local ORIG_FUNC=$(declare -f $1)
    local NEWNAME_FUNC="$2${ORIG_FUNC#$1}"
    eval "$NEWNAME_FUNC"
}
#兼容旧版本的bash-completion
if test -z "$(typeset -f _compopt_o_filenames)";then
    # This function turns on "-o filenames" behavior dynamically. It is present
    # for bash < 4 reasons. See http://bugs.debian.org/272660#64 for info about
    # the bash < 4 compgen hack.
    _compopt_o_filenames() {
        # We test for compopt availability first because directly invoking it on
        # bash < 4 at this point may cause terminal echo to be turned off for some
        # reason, see https://bugzilla.redhat.com/653669 for more info.
        type compopt &>/dev/null && compopt -o filenames 2>/dev/null || \
            compgen -f /non-existing-dir/ >/dev/null
    }
fi
_py_completion() {
    local IFS=$'\t\n'
    local cur _dname_real dname_real bname_real dname bname sep found var var1 same isAllSame len index hasHanzi
    local -a list sys_list

    cur="$(_get_cword)"
    __MYLOG "cur=${cur}"
    if [ "${cur:${#cur}-1}" = "/" ];then
        dname="${cur}"
        bname=""
        sep=""
    else
        dname="$(dirname "$cur")";
        bname="$(basename "$cur")";
        if [[ "$dname" == "/" ]];then
            sep=""
        else
            sep="/"
        fi
    fi

    #用于消除转义符 \
    dname_real="${dname//\\/}"
    bname_real="${bname//\\/}"

    if [ "${cur:0:1}" = "~" ];then
        dname_real="${dname_real#${HOME}}"
    fi

    test -z "$bname_real" && return 0;
    eval _dname_real="$dname"
    test ! -d "$_dname_real" && return 0;
    cd $_dname_real

    __MYLOG dname_real="$dname_real"
    __MYLOG _dname_real="$_dname_real"
    __MYLOG bname_real="$bname_real"
    __MYLOG sep="$sep"

    if [[ "$1" == "-d" ]];then
        __MYLOG "has -d"
        if [ "$__HAS_LOG" = "1" ];then
            list=($(compgen -d|sort|pinyinmatch "$bname_real" 2>${__logfile}))
        else
            list=($(compgen -d|sort|pinyinmatch "$bname_real"))
        fi
    else
        if [ "$__HAS_LOG" = "1" ];then
            list=($(compgen -f|sort|pinyinmatch "$bname_real" 2>${__logfile}))
        else
            list=($(compgen -f|sort|pinyinmatch "$bname_real"))
        fi
        [ ${#list[@]} -ne 0 ] && _compopt_o_filenames
    fi
    cd $OLDPWD
    sys_list=("${COMPREPLY[@]}")

    __MYLOG list="${list[@]}"
    __MYLOG sys_list="${sys_list[@]}"

    if [ ${#list[@]} -eq 1 ];then
        if [ "${list[0]}" = "$bname_real" ];then # 如果关键字和查询出来的是相同，则采取系统的集合
            # 出去重复的COMPREPLY
            COMPREPLY=()
            for var in "${sys_list[@]}";do
                found=0
                for var1 in "${COMPREPLY[@]}";do
                    if [ "$var" = "$var1" ];then
                        found=1
                    fi
                done
                if [ "$found" = "0" ];then
                    COMPREPLY=("${COMPREPLY[@]}" "${var}");
                fi
            done
        else
            if [ "$dname_real" != "." ];then
                COMPREPLY=("${dname_real}${sep}${list[0]}")
            else
                COMPREPLY=("${list[0]}")
            fi
        fi
    elif [ "$dname_real" != "." ];then
        COMPREPLY=()
        for var in "${list[@]}";do
            COMPREPLY=("${COMPREPLY[@]}" "${dname_real}${sep}${var}")
        done
    else
        COMPREPLY=("${list[@]}")
    fi

    len=${#COMPREPLY[@]}
    if [[ ${len} -gt 1 ]];then
        # 如果全部开头有相同的部分，则可以用数字选择
        same=""
        index=0
        while [ 1 ];do
            isAllSame=1
            var1="${COMPREPLY[0]:${index}:1}"
            for var in "${COMPREPLY[@]}";do
                if [ "${var:${index}:1}" != "${var1}" ];then
                    isAllSame=0
                fi
            done
            if [ "$isAllSame" = "1" ];then
                same="${same}${COMPREPLY[0]:${index}:1}"
            else
                break
            fi
            ((index++))
        done
        __MYLOG same=${same}
        if [ -n "$same" ];then
            if [ "${same:${#same}-1}" = "/" ];then
                bname=""
            else
                bname="$(basename "$same")";
            fi
            __MYLOG bname=${bname}
            if [[ -n "$bname" && -n "$bname_real" && "$bname_real" != "${bname:0:${#bname_real}}" ]];then
                COMPREPLY=("+[1-${len}]选择:" "${COMPREPLY[@]}")
            elif [ -z "$bname" ];then
                hasHanzi=$(echo "${list[@]}"|grep "[^ -~]")
                if [ -n "$hasHanzi" ];then
                    COMPREPLY=("+[1-${len}]选择:" "${COMPREPLY[@]}")
                fi
            fi
        fi
    fi

    __MYLOG COMPREPLY="${COMPREPLY[@]}"
}

_py_save_function _filedir _py_bak_filedir

_filedir() {
    _py_bak_filedir $@
    _py_completion $@
}

_py_save_function _filedir_xspec _py_bak_filedir_xspec

_filedir_xspec () {
    _py_bak_filedir_xspec $@
    _py_completion $@
}

unset -f _py_save_function
